home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 24
/
Amiga Format AFCD24 (Feb 1998, Issue 108).iso
/
-in_the_mag-
/
emulation
/
amiga
/
uae-0.7.0b2
/
src
/
filesys.asm
< prev
next >
Wrap
Assembly Source File
|
1998-01-20
|
8KB
|
370 lines
SECTION code
; This file can be translated with A68k or PhxAss and then linked with BLink
; to produce an Amiga executable. Make sure it does not contain any
; relocations, then run it through the filesys.sh script
dc.l 16
our_seglist:
dc.l 0 ;/* NextSeg */
start:
bra filesys_mainloop
dc.l make_dev-start
dc.l filesys_init-start
dc.l exter_server-start
dc.l bootcode-start
bootcode:
lea.l doslibname(pc),a1
jsr.l -96(a6) ; FindResident
move.l d0,a0
move.l 22(a0),d0
move.l d0,a0
jsr (a0)
rts
exter_data:
exter_server:
movem.l a2,-(sp)
moveq.l #0,d0
jsr.l $F0FF50
tst.l d0
beq.b exter_server_exit
; This is the hard part - we have to send some messages.
move.l 4.w,a6
EXTS_loop:
moveq.l #2,d0
jsr.l $F0FF50
tst.l d0
beq.b EXTS_done
move.l d0,a2
moveq.l #3,d0
jsr.l $F0FF50
move.l a2,a0
move.l d0,a1
jsr -366(a6) ; PutMsg
bra.b EXTS_loop
EXTS_done:
moveq.l #4,d0
jsr.l $F0FF50
moveq.l #1,d0 ; clear Z - it was for us.
exter_server_exit:
movem.l (sp)+,a2
rts
filesys_init:
movem.l d0-d7/a0-a6,-(sp)
move.l 4.w,a6
move.l $F0FFFC,a5 ; filesys base
lea.l explibname(pc),a1 ; expansion lib name
moveq.l #36,d0
moveq.l #0,d5
jsr.l -552(a6) ; OpenLibrary
tst.l d0
bne.b FSIN_explibok
lea.l explibname(pc),a1 ; expansion lib name
moveq.l #0,d0
moveq.l #1,d5
jsr.l -552(a6) ; OpenLibrary
FSIN_explibok:
move.l d0,a4
moveq.l #88,d0
moveq.l #1,d1 ; MEMF_PUBLIC
jsr.l -198(a6) ; AllocMem
move.l d0,a3 ; param packet
moveq.l #84,d7 ; initialize it
FSIN_loop:
move.l 0(a5,d7.l),0(a3,d7.l)
subq.l #4,d7
bcc.b FSIN_loop
moveq.l #0,d6
FSIN_init_units:
cmp.l $10c(a5),d6
bcc.b FSIN_units_ok
move.l a3,a0
movem.l d6/a3,-(sp)
move.l #1,d7
bsr.b make_dev
movem.l (sp)+,d6/a3
addq.l #$1,d6
bra.b FSIN_init_units
FSIN_units_ok:
move.l 4.w,a6
move.l a4,a1
jsr.l -414(a6) ; CloseLibrary
bsr.b setup_exter
move.l 4.w,a6
jsr.l $F0FF80
moveq.l #3,d1
moveq.l #-10,d2
move.l #$200000,a0
sub.l a0,d0
bcs.b FSIN_chip_done
beq.b FSIN_chip_done
moveq.l #0,d4
move.l d4,a1
jsr -618(a6)
FSIN_chip_done
movem.l (sp)+,d0-d7/a0-a6
general_ret:
rts
setup_exter:
move.l 4.w,a6
moveq.l #26,d0
move.l #$10001,d1
jsr -198(a6) ; AllocMem
move.l d0,a1
lea.l exter_name(pc),a0
move.l a0,10(a1)
lea.l exter_data(pc),a0
move.l a0,14(a1)
lea.l exter_server(pc),a0
move.l a0,18(a1)
moveq.l #13,d0
jmp.l -168(a6) ; AddIntServer
make_dev: ; IN: A0 param_packet, D6: unit_no, D7: boot, A4: expansionbase
move.l $F0FFFC,a5 ; filesys base
jsr $F0FF28 ; fill in unit-dependent info, return 1 if hardfile.
move.l d0,d3
; Don't init hardfiles if < V36
and.l d5,d0
bne.b general_ret
move.l a4,a6
jsr.l -144(a6) ; MakeDosNode()
move.l d0,a3 ; devicenode
jsr.l $F0FF20 ; record in ui.startup
moveq.l #0,d0
move.l d0,8(a3) ; dn_Task
move.l d0,16(a3) ; dn_Handler
move.l d0,32(a3) ; dn_SegList
tst.l d3
bne.b MKDV_doboot
MKDV_is_filesys:
move.l #4000,20(a3) ; dn_StackSize
lea.l our_seglist(pc),a1
move.l a1,d0
lsr.l #2,d0
move.l d0,32(a3) ; dn_SegList
move.l #-1,36(a3) ; dn_GlobalVec
MKDV_doboot:
tst.l d7
beq.b MKDV_noboot
move.l 4.w,a6
moveq.l #20,d0
moveq.l #0,d1
jsr.l -198(a6) ; AllocMem
move.l d0,a1 ; bootnode
moveq.l #0,d0
move.l d0,(a1)
move.l d0,4(a1)
move.w d0,14(a1)
move.w #$10FF,d0
sub.b d6,d0
move.w d0,8(a1)
move.l $104(a5),10(a1) ; filesys_configdev
move.l a3,16(a1) ; devicenode
lea.l 74(a4),a0 ; MountList
jmp.l -270(a6) ; Enqueue()
MKDV_noboot:
move.l a3,a0
moveq.l #0,d1
move.l d1,a1
moveq.l #-1,d0
move.l a4,a6 ; expansion base
jmp.l -150(a6) ; AddDosNode
filesys_mainloop:
move.l 4.w,a6
moveq.l #0,d0
move.l d0,a1
jsr -294(a6) ; FindTask
move.l d0,a0
lea.l $5c(a0),a5 ; pr_MsgPort
; Open DOS library
lea.l doslibname(pc),a1
moveq.l #0,d0
jsr -552(a6) ; OpenLibrary
move.l d0,a2
; Allocate some memory. Usage:
; 0: lock chain
; 4: command chain
; 8: second thread's lock chain
; 12: dummy message
; 32: the volume (80+44+1 bytes)
move.l #80+44+1+20+12,d0
move.l #$10001,d1 ; MEMF_PUBLIC | MEMF_CLEAR
jsr.l -198(a6) ; AllocMem
move.l d0,a3
moveq.l #0,d6
move.l d6,(a3)
move.l d6,4(a3)
move.l d6,8(a3)
moveq.l #0,d5 ; No commands queued.
; Fetch our startup packet
move.l a5,a0
jsr -384(a6) ; WaitPort
move.l a5,a0
jsr -372(a6) ; GetMsg
move.l d0,a4
move.l 10(a4),d3 ; ln_Name
moveq.l #0,d0
jsr.l $F0FF40
bra.b FSML_Reply
; We abuse some of the fields of the message we get. Offset 0 is
; used for chaining unprocessed commands, and offset 1 is used for
; indicating the status of a command. 0 means the command was handed
; off to some UAE thread and did not complete yet, 1 means we didn't
; even hand it over yet because we were afraid that might blow some
; pipe limit, and -1 means the command was handed over and has completed
; processing by now, so it's safe to reply to it.
FSML_loop:
move.l a5,a0
jsr -384(a6) ; WaitPort
move.l a5,a0
jsr -372(a6) ; GetMsg
move.l d0,a4
move.l 10(a4),d3 ; ln_Name
bne.b FSML_FromDOS
; It's a dummy packet indicating that some queued command finished.
moveq.l #1,d0
jsr.l $F0FF50
; Go through the queue and reply all those that finished.
lea.l 4(a3),a2
move.l (a2),a0
FSML_check_old:
move.l a0,d0
beq.b FSML_loop
move.l (a0),a1
move.l d0,a0
; This field may be accessed concurrently by several UAE threads.
; This _should_ be harmless on all reasonable machines.
move.l 4(a0),d0
bpl.b FSML_check_next
movem.l a0/a1,-(a7)
move.l 10(a0),a4
bsr.b ReplyOne
subq.l #1,d5 ; One command less in the queue
movem.l (a7)+,a0/a1
move.l a1,(a2)
move.l a1,a0
bra.b FSML_check_old
FSML_check_next:
move.l a0,a2
move.l a1,a0
bra.b FSML_check_old
FSML_FromDOS:
; Limit the number of outstanding started commands. We can handle an
; unlimited number of unstarted commands.
cmp.l #20,d5
bcs FSML_DoCommand
; Too many commands queued.
moveq.l #1,d0
move.l d0,4(a4)
bra.b FSML_Enqueue
FSML_DoCommand:
bsr.b LockCheck ; Make sure there are enough locks for the C code to grab.
jsr.l $F0FF30
tst.l d0
beq.b FSML_Reply
; The command did not complete yet. Enqueue it and increase number of
; queued commands
; The C code already set 4(a4) to 0
addq.l #1,d5
FSML_Enqueue:
move.l 4(a3),(a4)
move.l a4,4(a3)
bra.b FSML_loop
FSML_Reply:
move.l d3,a4
bsr.b ReplyOne
bra.b FSML_loop
ReplyOne:
move.l (a4),a1 ; dp_Link
move.l 4(a4),a0 ; dp_Port
move.l a5,4(a4)
jmp -366(a6) ; PutMsg
; ugly code to avoid calling AllocMem / FreeMem from native C code.
; We keep a linked list of 3 locks. In theory, only one should ever
; be used. Before handling every packet, we check that the list has the
; right length.
LockCheck:
move.l d5,-(a7)
moveq.l #-4,d5 ; Keep three locks
move.l (a3),a2
move.l a2,d7
LKCK_Loop:
move.l a2,d1
beq LKCK_ListEnd
addq.l #1,d5
beq.b LKCK_TooMany
move.l a2,a1
move.l (a2),a2
bra.b LKCK_Loop
LKCK_ListEnd:
addq.l #1,d5
beq.b LKCK_ret
move.l d7,a2
moveq.l #24,d0 ; sizeof Lock is 20, 4 for chain
moveq.l #1,d1 ; MEMF_PUBLIC
jsr.l -198(a6) ; AllocMem
addq.w #1,d6
move.l d0,a2
move.l d7,(a2)
move.l a2,d7
bra.b LKCK_ListEnd
LKCK_TooMany:
move.l (a2),d0 ; We have too many, but we tolerate that to some extent.
beq.b LKCK_ret
move.l d0,a0
move.l (a0),d0
beq.b LKCK_ret
move.l d0,a0
move.l (a0),d0
beq.b LKCK_ret
moveq.l #0,d0 ; Now we are sure that we really have too many. Delete some.
move.l d0,(a1)
LKCK_TooManyLoop:
move.l a2,a1
move.l (a1),a2
moveq.l #24,d0
jsr -210(a6) ; FreeMem
add.l #$10000,d6
move.l a2,d0
bne.b LKCK_TooManyLoop
LKCK_ret:
move.l d7,(a3)
move.l (a7)+,d5
rts
exter_name: dc.b 'UAE filesystem',0
doslibname: dc.b 'dos.library',0
explibname: dc.b 'expansion.library',0
END